﻿namespace AB.ServiceDirectory.Dao
{
    using System.Data.SqlClient;
    using System.Transactions;
    using Entities;
    using System.Linq;
    using System;
    using Commons.DataFilters;

    /// <summary>
    /// DepartmentDao class
    /// </summary>
    [Serializable]
    public class DepartmentDao
    {
        /// <summary>
        /// Data Context
        /// </summary>
        [NonSerialized]
        private readonly ServicesDirectoryDataContext _context = DB.Context;

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="max">The max.</param>
        /// <returns>Department list query</returns>
        public IQueryable<Department> GetList(DepartmentFilter filter, string sortType, int startRowIndex, int max)
        {
            var data = from d in _context.Departments
                       select d;

            // 1. Filter by condition
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            // 2. Sorting
            data = GetListSort(data, sortType);

            // 3. Limit the rows
            data = data.Skip(startRowIndex).Take(max);
            return data;
        }

        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<Department> GetListSort(IQueryable<Department> data, string sortType)
        {
            var sortDescending = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                var values = sortType.Split(' ');
                sortType = values[0];
                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }
                switch (sortType)
                {
                    case "DepartmentName":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.DepartmentName)
                                   : data.OrderBy(g => g.DepartmentName);
                        break;
                    case "AddressLine1":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.Address)
                                   : data.OrderBy(g => g.Address);
                        break;
                    case "Postcode":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.Address.Postcode)
                                   : data.OrderBy(g => g.Address.Postcode);
                        break;
                    case "Contact":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.Contact)
                                   : data.OrderBy(g => g.Contact);
                        break;
                    case "IsActive":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.IsActive)
                                   : data.OrderBy(g => g.IsActive);
                        break;
                    default:
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.DepartmentId)
                                   : data.OrderBy(g => g.DepartmentId);
                        break;
                }
            }
            return data;
        }

        /// <summary>
        /// Gets the list query.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="filter">The filter.</param>
        /// <returns>Department list query</returns>
        private static IQueryable<Department> GetListQuery(IQueryable<Department> data, DepartmentFilter filter)
        {
            data = data.Where(d => d.DirectorateId == filter.DirectorateId);
            if (filter.BeginningLetters != null)
            {
                data = data.Where(g => filter.BeginningLetters.Contains(g.DepartmentName[0].ToString()));
            }

            if (!filter.IncludeInactive)
            {
                data = data.Where(g => g.IsActive);
            }
            return data;
        }

        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public int GetListCount(DepartmentFilter filter)
        {
            var data = from gor in _context.Departments
                       select gor;
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }
            return data.Count();

        }
        /// <summary>
        /// Gets the department id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Department GetDepartmentId(int id)
        {
            var department = _context.Departments.FirstOrDefault(g => g.DepartmentId == id);
            return department;
        }

        /// <summary>
        /// Adds the department.
        /// </summary>
        /// <param name="newDepartment">The new department.</param>
        /// <returns></returns>
        public bool AddDepartment(Department newDepartment)
        {
            try
            {
                using (var transaction = new TransactionScope())
                {
                    _context.Departments.InsertOnSubmit(newDepartment);
                    _context.SubmitChanges();
                    transaction.Complete();
                    return true;
                }
            }
            catch (SqlException exception)
            {
                Log.GetLog(this).Error(exception);
                return false;
            }
        }

        /// <summary>
        /// Edits the department.
        /// </summary>
        /// <param name="newDepartment">The new department.</param>
        /// <returns></returns>
        public bool EditDepartment(Department newDepartment)
        {
            var oldDepartment = _context.Departments.FirstOrDefault(d => d.DepartmentId == newDepartment.DepartmentId);
            if (oldDepartment != null)
            {
                oldDepartment.DepartmentName = newDepartment.DepartmentName;
                oldDepartment.ShortDescription = newDepartment.ShortDescription;
                oldDepartment.FullDescription = newDepartment.FullDescription;
                oldDepartment.CityTown = newDepartment.CityTown;

                oldDepartment.County = newDepartment.County;
                oldDepartment.CountryId = newDepartment.CountryId;
                oldDepartment.Fax = newDepartment.Fax;
                oldDepartment.PhoneNumber = newDepartment.PhoneNumber;
                oldDepartment.Email = newDepartment.Email;
                oldDepartment.WebAddress = newDepartment.WebAddress;
                oldDepartment.DirectorateId = newDepartment.DirectorateId;

                // Ref Key
                oldDepartment.BusinessType = newDepartment.BusinessId != null ? _context.BusinessTypes.FirstOrDefault(b => b.BusinessId == newDepartment.BusinessId) : null;
                oldDepartment.Address = newDepartment.AddressId != null ? _context.Addresses.FirstOrDefault(a => a.AddressId == newDepartment.AddressId) : null;
                oldDepartment.Contact = newDepartment.ContactId != null ? _context.Contacts.FirstOrDefault(a => a.ContactId == newDepartment.ContactId) : null;

                _context.SubmitChanges();
                return true;
            }
            return false;
        }

        /// <summary>
        /// Checks the name of the department.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public bool CheckDepartmentName(string name)
        {
            var department = _context.Departments.FirstOrDefault(d => d.DepartmentName.Equals(name));
            return department != null;
        }

        /// <summary>
        /// Checks the department short description.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public bool CheckDepartmentShortDescription(string name)
        {
            var description = _context.Departments.FirstOrDefault(d => d.ShortDescription.Equals(name));
            return description != null;
        }

        /// <summary>
        /// Sets the department status.
        /// </summary>
        /// <param name="departmentId">The department id.</param>
        /// <param name="status">if set to <c>true</c> [status].</param>
        /// <returns>true/false</returns>
        public bool SetDepartmentStatus(int departmentId, bool status)
        {
            var department = _context.Departments.FirstOrDefault(o => o.DepartmentId == departmentId);
            if (department != null)
            {
                department.IsActive = status;
                return true;
            }
            return false;
        }
    }
}
